<template>
  <div class="version-detail" v-loading="loading">

        <topTitle title="基础信息"/>
        <el-form
            :model="detail"
            :rules="rules"
            ref="ruleForm"
            hide-required-asterisk
            label-width="120px">
            <!-- 添加平台信息 -->
            <el-form-item label="平台">
                <el-select :disabled="version ? true : false" v-model="detail.name" style="width:220px" @change="selectPlatChange">
                    <el-option v-for="item in platFormList" :key="item.id" :label="item.name" :value="item.name"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="版本号" prop="version">
                <div class="version-box">
                    <el-input v-model.trim="detail.version" style="width:220px" :disabled="!!version || disabledVersion"></el-input>
                    <div class="disabled-version" v-if="!version">
                        <template v-if="disabledVersion">
                            <el-button size="small" type="danger" @click="disabledVersion = false">取消</el-button>
                            <span class="version-desc">*取消锁定后需要重新上传apk包</span>
                        </template>
                        <template v-else>
                            <el-button size="small" type="success" @click="disabledVersionInput">锁定</el-button>
                            <span class="version-desc">*锁定版本号后方可上传apk包</span>
                        </template>
                    </div>
                </div>
            </el-form-item>
            <el-form-item label="更新方式" prop="updateType">
                <el-select v-model="detail.updateType" style="width:220px">
                    <el-option label="强制更新" :value="2"></el-option>
                    <el-option label="非强制更新" :value="1"></el-option>
                    <el-option label="非强制更新不弹窗" :value="0"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="最低兼容版本" prop="lowVersion" v-if="detail.updateType === 1 || detail.updateType === 0">
                <el-input v-model.trim="detail.lowVersion" style="width:220px"></el-input>
            </el-form-item>
            <el-form-item label="免打扰版本" prop="highVersion">
                <el-input v-model.trim="detail.highVersion" style="width:220px"></el-input>
            </el-form-item>
            <el-form-item label="更新时间" prop="beginTime">
                <el-date-picker
                    popper-class="channel-picker"
                    :picker-options="pickerOptions"
                    v-model="detail.beginTime"
                    type="datetime"
                    placeholder="选择更新时间">
                </el-date-picker>
            </el-form-item>
            <el-form-item label="更新标题" prop="updateTitle">
                <el-input v-model.trim="detail.updateTitle" show-word-limit maxlength="10" style="width:220px"></el-input>
            </el-form-item>
            <el-form-item label="更新文案" prop="updateContent">
                <el-input v-model="detail.updateContent" type="textarea" maxlength="100" show-word-limit :rows="5"></el-input>
            </el-form-item>
        </el-form>

        <!-- 渠道包  没有版本号不展示 -->
        <template v-if="version || disabledVersion">

            <!-- 如果是IOS则只展示保存按钮 -->
            <topTitle title="渠道包" v-if="detail.name.indexOf('iOS') <= -1" />
            <div class="btn-box">
                <el-upload
                    v-if="detail.name.indexOf('iOS') <= -1"
                    action="string"
                    accept=".apk"
                    multiple
                    :show-file-list="false"
                    :http-request="uploadChange">
                    <el-button size="small" type="primary">批量上传</el-button>
                </el-upload>

                <el-button type="success" style="margin-left:20px" size="mini" :loading="saveLoading" @click="saveForm">保存</el-button>
            </div>

            <div class="channel-list-box" v-if="detail.name.indexOf('iOS') <= -1">
                <ul class="channel-title">
                    <li class="channel-title-item center" style="width:150px;">渠道</li>
                    <li class="channel-title-item center" style="flex:1;">渠道包</li>
                </ul>

                <ul class="channel-content" v-for="(item, index) in channelList" :key="index">
                    <li class="channel-content-item center" style="width:150px;">{{item.desc}}</li>
                    <li class="channel-content-item" style="flex:1;">
                        <template v-if="item.percent">
                            <div class="reset-upload">
                                <el-progress :percentage="item.percent" style="width:500px;"></el-progress>
                                <el-button size="small" type="danger" style="margin-left:10px;" @click="cancleUpload(item)">取消上传</el-button>
                            </div>
                        </template>
                        <template v-else>
                            <div v-if="item.downloadUrl" class="reset-upload">
                                <span v-if="item._noApk" style="color:#F56C6C;">未检测到该渠道包</span>
                                <span v-else>{{item.downloadUrl}}</span>
                                <el-upload
                                    class="reset-upload-btn"
                                    action="string"
                                    accept=".apk"
                                    :show-file-list="false"
                                    :http-request="uploadOnceChange(item)">
                                    <el-button size="small" type="primary">重新上传</el-button>
                                </el-upload>
                            </div>
                            <div v-else class="reset-upload">
                                <el-upload
                                    class="reset-upload-btn"
                                    action="string"
                                    accept=".apk"
                                    :show-file-list="false"
                                    :http-request="uploadOnceChange(item)">
                                    <el-button size="small" type="primary">点击上传</el-button>
                                </el-upload>
                            </div>
                        </template>
                    </li>
                </ul>
            </div>
        </template>

  </div>
</template>

<script>
import { formatDate } from '@/utils/utils'
import OSS from 'ali-oss'

export default {
    data () {
        // TODO:校验版本号
        var checkVersion1 = (rule, value, callback) => {
            if (!/^\d+(?:\.\d+){2,3}$/i.test(value)) {
                callback(new Error('请输入正确版本号'))
            } else {
                callback()
            }
        }
        var checkVersion2 = (rule, value, callback) => {
            // if (value <= this.minVersion && !this.version) {
            //     callback(new Error('当前输入版本号小于最新版本号'))
            // } else {
            //     callback()
            // }
            callback()
        }
        var checkLowVersion1 = (rule, value, callback) => {
            if (value && !/^\d+(?:\.\d+){2,3}$/i.test(value)) {
                callback(new Error('请输入正确版本号'))
            } else {
                callback()
            }
        }
        var checkLowVersion2 = (rule, value, callback) => {
            if (value && value > this.detail.version) {
                callback(new Error('最低兼容版本号应小于本次更新版本号'))
            } else {
                callback()
            }
        }
        var checkBeginTime = (rule, value, callback) => {
            // if (+value < +new Date()) {
            //     callback(new Error('请重新确认更新时间！'))
            // } else {
            // }
            callback()
        }
        return {
            loading: false,
            disabledVersion: false, // 是否禁用版本号
            version: '',
            pickerOptions: {
                disabledDate (time) {
                    return time.getTime() < Date.now() - 1000 * 60 * 60 * 24
                },
                selectableRange: '00:00:00 - 23:59:59'
            },
            detail: {
                version: '', // 版本
                lowVersion: '', // 最低兼容版本
                updateType: 1, // 更新方式
                beginTime: '', // 更新时间
                updateTitle: '发现新版本',
                updateContent: '', // 更新文案
                name: '' 
            }, // 详情
            rules: { // 详情校验
                version: [
                    { required: true, message: '请输入版本', trigger: 'blur' },
                    { validator: checkVersion2, trigger: 'blur' },
                    { validator: checkVersion1, trigger: 'blur' }
                ],
                lowVersion: [
                    { validator: checkLowVersion1, trigger: 'blur' },
                    { validator: checkLowVersion2, trigger: 'blur' }
                ],
                beginTime: [
                    { type: 'date', required: true, message: '请选择更新时间', trigger: 'change' },
                    { validator: checkBeginTime, trigger: 'blur' }
                ],
                updateTitle: [
                    { required: true, message: '请输入更新标题', trigger: 'blur' }
                ],
                updateContent: [
                    { required: true, message: '请输入更新文案', trigger: 'blur' }
                ]
            },
            saveLoading: false,
            channelList: [], // 渠道包列表
            platFormList: [],
            platObj: {}
        }
    },

    created () {
        this.minVersion = this.$route.query.main
        this.pickerOptions.selectableRange = formatDate((+new Date() + 10 * 60 * 1000), 'HH:MM:SS') + ' - 23:59:59'
        this.version = this.$route.query.version
        this.packageName = this.$route.query.packageName
        this.platformId = this.$route.query.platformId
        if (this.version) this.getDetail()
        this.selectPlatForm()
    },

    mounted() {
        
    },

    methods: {
        // 获取平台下拉列表
        async selectPlatForm () {
            let res = await this.$http.get('/apkManage/selectPlatForm')
            if (res.code === '0') {
                this.platFormList = res.data
                if (!this.version) {
                    this.detail.name = res.data[0].name
                    this.platObj = {
                        id: res.data[0].id,
                        name: res.data[0].name,
                        packageName: res.data[0].packageName
                    }
                }
            } else {
                this.$message({
                    type: 'error',
                    message: res.desc
                })
            }
        },
        selectPlatChange(val) {
            this.detail.name = val
            this.platFormList.forEach((item) => {
                if (item.name === this.detail.name) {
                    this.platObj = item
                }
            })
        },

        // 获取详情
        async getDetail (obj) {
            // 如果是 详情则不让选择
            if (!this.version) {
                return
            }
            this.loading = true
            let res = await this.$http.get('/apkManage/getApkDetail', {
                params: {
                    version: this.version,
                    packageName: (obj && obj.packageName) || this.packageName,
                    platformId: (obj && obj.platformId) || this.platformId,           
                    type: (obj && obj.type) || this.$route.query.type
                }
            })
            if (res.code === '0') {
                if (res.data.beginTime) {
                    res.data.beginTime = new Date(res.data.beginTime)
                }
                this.detail = res.data
                this.platObj = {
                    id: res.data.platformId,
                    name: res.data.name,
                    packageName: res.data.packageName
                }

                this.getChannel(this.platObj, this.version, async (item) => {
                    try {
                        await this.$http.head(item.downloadUrl)
                    } catch (error) {
                        item._noApk = true
                    }
                })
            } else {
                this.$message({
                    type: 'error',
                    message: res.desc
                })
                this.loading = false
            }
        },

        // 获取上传版本信息
        async getChannel (obj, version, cb) {
            this.loading = true
            let res = await this.$http.get('/apkManage/getChannel', {
                params: {
                    version,
                    platformId: obj && obj.id
                }
            })
            if (res.code === '0') {
                res.data.forEach(item => {
                    item.percent = 0
                    item.uploading = false
                    item._noApk = false
                    cb && cb(item)
                })
                this.channelList = res.data
            } else {
                this.$message({
                    type: 'error',
                    message: res.desc
                })
            }
            this.loading = false
        },

        // 锁定版本号
        disabledVersionInput () {
            this.$refs.ruleForm.validateField('version', (valid) => {
                if (!valid) {
                    this.disabledVersion = true
                    this.getChannel(this.platObj, this.detail.version, (item) => {
                        item.downloadUrl = ''
                    })
                } else {
                    return false
                }
            })
        },

        // 批量上传获取文件
        uploadChange (file) {
            // 选取上传文件
            this.file = file.file
            // 获取上传文件名，用来比对
            let fileName = file.file.name
            if (!this.file) return
            // 批量上传判断是否比对成功
            let flag = true
            this.channelList.forEach(item => {
                // 目标文件名
                let name = 'qugame-' + item.channel
                // 如果上传的文件名与目标相符
                if (fileName.includes(name)) {
                    // 批量上传
                    this.getOssUploadSign(item, file.file)
                    flag = false
                }
            })
            // 都比对不上，弹窗警告文件名不对
            if (flag) {
                this.$message({
                    type: 'info',
                    message: '批量上传请认真核对文件名'
                })
            }
        },

        // 单个apk上传
        uploadOnceChange (item) {
            return (file) => {
                if (!file.file) return
                this.getOssUploadSign(item, file.file)
            }
        },

        // 获取上传参数
        async getOssUploadSign (item, file) {
            item._noApk = false // 取消提示
            this.detail.longSize = file.size
            this.detail.size = (file.size / 1024 / 1024).toFixed(1) + 'MB'
            let res = await this.$http.get('/file/getOssUploadSign')
            if (res.code === '0') {
                res.data = res.data || {}
                item.copyKey = ''
                item.key = 'apk/' + this.detail.version + '/' + item.fileName
                // 区分不同的包 1、安卓端趣游戏App 2、iOS端趣游戏App 3、安卓端登号器 4、安卓端0元租号App 5、h5端登号器
                let platformId = this.platObj.id + '' ||  this.$route.query.platformId + ''
                console.log(platformId, 'platformId', typeof platformId)
                if (platformId === '1') {
                    item.key = `apk/${this.detail.version}/${item.fileName}`
                    item.copyKey = `apk/c/${item.fileName}`
                }

                if (platformId === '3') {
                    item.key = `launch/${this.detail.version}/${item.fileName}`
                    item.copyKey = `launch/c/${item.fileName}`
                }

                if (platformId === '4') {
                    item.key = `apk2/${this.detail.version}/${item.fileName}`
                    item.copyKey = `apk2/c/${item.fileName}`
                }

                let url = res.data.downloadUrl
                let arr = url.split('static/apk')
                // 获取下载地址
                item._downloadUrl = arr[0] + item.key
                item.aliClient = new OSS({
                    region: res.data.region,
                    accessKeyId: res.data.accessKeyId,
                    accessKeySecret: res.data.accessKeySecret,
                    bucket: res.data.bucket
                })
                // 开始分片上传
                this.multipartUpload(item, file)
            } else {
                this.$message({
                    type: 'error',
                    message: res.desc
                })
            }
        },

        // 分片上传
        async multipartUpload (item, file) {
            item.uploading = true
            try {
                // object-key可以自定义为文件名（例如file.txt）或目录（例如abc/test/file.txt）的形式，实现将文件上传至当前Bucket或Bucket下的指定目录。
                await item.aliClient.multipartUpload(item.key, file, {
                    progress: (p, checkpoint) => {
                        p = parseInt(p * 100)
                        item.percent = p || 1
                        if (item.percent >= 100) {
                            // 上传完毕
                            item.uploading = false
                            // 上报下载地址
                            item.downloadUrl = item._downloadUrl
                            item.percent = 0

                            // 如果需要 copy 
                            if (item.copyKey) {
                                item.aliClient.copy(item.copyKey, item.key).then((res) => {
                                    console.log(res, 'copy 成功');
                                }).catch(e => {
                                    console.log(e, 'copy 失败');
                                })

                                // try {
                                //     let result = item.aliClient.list({
                                //         prefix: 'apk/',
                                //         delimiter: '/'
                                //     });
                                //     console.log(result, '上传成功路径')
                                // } catch (e) {
                                //     console.log(e);
                                // }
                            }
                            
                        }
                    }
                })
            } catch (e) {
            }
        },

        // 取消上传
        cancleUpload (item) {
            item.aliClient.cancel()
            item.percent = 0
        },

        // 保存前校验
        saveForm () {
            this.$refs.ruleForm.validate((valid) => {
                if (valid) {
                    this.checkChannel()
                } else {
                    return false
                }
            })
        },

        // 校验渠道包
        checkChannel () {
            // 保存loading
            this.saveLoading = true
            // 如果是修改，直接调用保存接口
            if (this.detail.id) {
                this.saveChannel()
            } else {
                // 添加定时器3s，防止OSS apk包未上传成功
                setTimeout(async () => {
                    let allFlag = 0 // 校验，是否每个渠道都上传apk包了
                    let urlFlag = '' // 校验 所有url是否有效
                    this.channelList.forEach(async (item, index) => {
                        if (item.downloadUrl) {
                            try {
                                await this.$http.head(item.downloadUrl)
                            } catch (error) {
                                urlFlag = item.desc
                                item.downloadUrl = ''
                            }
                        } else {
                            allFlag++
                        }
                        // 如果是最后一个包
                        if (index === this.channelList.length - 1) {
                            // url 无效 不允许保存
                            if (urlFlag) {
                                this.$message({
                                    type: 'error',
                                    message: `${urlFlag} 渠道包上传有误，请重新上传`
                                })
                                this.saveLoading = false
                                return
                            }

                            // 部分包未上传
                            // if (allFlag === this.channelList.length) {
                            //     this.$message({
                            //         type: 'error',
                            //         message: '请至少上传一个渠道包！'
                            //     })
                            //     this.saveLoading = false
                            // } else 
                            if (allFlag > 0) {
                                this.$confirm(`系统检测有 ${allFlag} 个渠道包未上传, 是否强制保存?`, '警告', {
                                    confirmButtonText: '强制保存',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                    }).then(() => {
                                        this.saveChannel()
                                    }).catch(() => {
                                        this.saveLoading = false
                                        this.$message({
                                            type: 'info',
                                            message: '已取消保存！'
                                        })
                                })
                                return
                            }
                            this.saveChannel()
                        }
                    })
                }, 3000)
            }
        },

        // 保存接口
        async saveChannel () {
            let params = { ...this.detail }
                if (params.updateType === 1 || params.updateType === 0) {
                    params.lowVersion = params.lowVersion || null
                } else {
                    params.lowVersion = null
                }
                params.type = 0
                console.log(this.platObj.id, 'this.platObj')
                params.packageName = this.platObj.packageName || this.$route.query.packageName
                params.platformId = this.platObj.id || this.$route.query.platformId
                console.log(params, 'params')
                // 格式化时间
                params.beginTime = formatDate(this.detail.beginTime, 'YYYY-MM-DD HH:MM:SS')
                let res = await this.$http.post('/apkManage/saveApk', params)
                if (res.code === '0') {
                    this.version = this.detail.version
                    res.data.beginTime = new Date(res.data.beginTime)
                    this.$message({
                        type: 'success',
                        message: '发布成功！'
                    })
                } else {
                    this.$message({
                        type: 'error',
                        message: res.desc
                    })
                }
                this.saveLoading = false
        }

    }
}
</script>

<style lang="scss" scoped>
    .version-detail {
        padding-bottom: 20px;
        .version-box {
            display: flex;
            align-items: center;
            .version-desc {
                margin-left: 10px;
                font-size: 12px;
                color: red;
            }
        }
        .disabled-version {
            margin-left: 10px;
        }
        // 渠道列表
        .channel-list-box {
            margin-top: 10px;
            width: 800px;
            border: 1px solid #ebeef5;
            border-bottom: none;
            border-right: none;
            .channel-title {
                display: flex;
                border-bottom: 1px solid #ebeef5;
                .channel-title-item {
                    padding: 10px;
                    border-right: 1px solid #ebeef5;
                    font-size: 14px;
                    font-weight: 700;
                    color: rgb(144, 147, 153);
                }
            }

            .channel-content {
                display: flex;
                border-bottom: 1px solid #ebeef5;
                .channel-content-item {
                    padding: 10px;
                    font-size: 14px;
                    border-right: 1px solid #ebeef5;
                    color: rgb(96, 98, 102);
                    word-break: break-all;
                    .reset-upload {
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        .reset-upload-btn {
                            margin-left: 10px;
                        }
                    }
                }
            }

            .center {
                display: flex;
                align-items: center;
                justify-content: center;
            }
        }

        .btn-box {
            display: flex;
        }
    }
</style>
<style lang="scss">
    .channel-picker {
        .el-button--text {
            display: none;
        }
    }
</style>
